package com.wondersgroup.insurance.dnuilearn.views.path;

import android.animation.Animator;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.support.annotation.Nullable;
import android.support.v4.view.GestureDetectorCompat;
import android.support.v4.widget.ViewDragHelper;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.wondersgroup.insurance.dnuilearn.R;

/**
 * Created by Administrator on 2017/5/27.
 */
/*1、气泡静止状态 -- 画气泡小球和数字

         2、气泡相连状态 --- 画两个相连的气泡小球（类似橡皮筋效果）、数字

         3、气泡分离状态 --- 单个气泡小球的拖动

         4、气泡消失状态 -- 爆炸动画

         5、气泡还原动画


         分解状态后，我们就来分析下我们要用到的技术点：

         1、跟path、绘图相关---相连的粘连效果（贝塞尔曲线）

         2、监听拖拽事件*/
public class QQBubble extends View {

    /**
     * 气泡默认状态--静止
     */
    private final int BUBBLE_STATE_DEFAUL = 0;
    /**
     * 气泡相连
     */
    private final int BUBBLE_STATE_CONNECT = 1;
    /**
     * 气泡分离
     */
    private final int BUBBLE_STATE_APART = 2;
    /**
     * 气泡消失
     */
    private final int BUBBLE_STATE_DISMISS = 3;

    int state = BUBBLE_STATE_DEFAUL;

    Paint mPaint;

    String text = "34";
    int textPadding = 10;
    int defaultTextSize = 30;
    int cX,cY;

    int defaultRadius = 30;
   final   float  scaleCircleFactor = 1.5f;
    int moveRadius = (int) (defaultRadius * scaleCircleFactor);


    int c1X = -1,c1Y =-1;


   final   int minDelta = 50;
   final int maxDelta = 300;

    boolean isShowBubble = false;

    /**
     *  气泡爆炸的图片id数组
     */
    private int[] mBurstDrawablesArray = {R.drawable.burst_1, R.drawable.burst_2
            , R.drawable.burst_3, R.drawable.burst_4, R.drawable.burst_5};

    /**
     *  气泡爆炸的bitmap数组
     */
    private Bitmap[] mBurstBitmapsArray;

    public QQBubble(Context context) {
        this(context, null);
    }

    public QQBubble(Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public QQBubble(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

        mBurstBitmapsArray = new Bitmap[mBurstDrawablesArray.length];
        for (int i = 0; i < mBurstDrawablesArray.length; i++) {
            //将气泡爆炸的drawable转为bitmap
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), mBurstDrawablesArray[i]);
            mBurstBitmapsArray[i] = bitmap;
        }
    }



    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        cX = w >>1;
        cY = h >> 1;

    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.drawColor(Color.WHITE, PorterDuff.Mode.CLEAR);
        drawDefaultText(canvas);

        if (isShowBubble){
            switch (state){
                case BUBBLE_STATE_DEFAUL:

                    break;
                case BUBBLE_STATE_CONNECT:{
                    mPaint.setColor(Color.RED);
                    mPaint.setStrokeWidth(4);
                    mPaint.setStyle(Paint.Style.FILL);
                    canvas.drawPath(besizlePath,mPaint);
                    drawMoveCircle(canvas);
                }

                break;
                case BUBBLE_STATE_APART:
                    drawMoveCircle(canvas);
                    break;
                case BUBBLE_STATE_DISMISS:
                    Bitmap bmp = mBurstBitmapsArray[bmpIndex];
                    canvas.drawBitmap(bmp,c1X - bmp.getWidth()/2, c1Y-bmp.getHeight(),mPaint);
                    break;
            }
        }

    }


    void drawDefaultText(Canvas canvas){
        canvas.save();
        canvas.translate(cX,cY);
        mPaint.setColor(Color.WHITE);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setTextSize(defaultTextSize);
        Rect rect = new Rect();
        mPaint.getTextBounds(text,0,text.length(),rect);
//        defaultRadius = (Math.max(rect.width(),rect.height())+textPadding*2)/2;

        mPaint.setColor(Color.RED);

        mPaint.setStyle(Paint.Style.FILL);

        canvas.drawCircle(0,0,defaultRadius,mPaint);
        mPaint.setColor(Color.WHITE);
        mPaint.setTextSize(defaultTextSize);
        mPaint.setStyle(Paint.Style.STROKE);
        canvas.drawText(text,0,text.length(),-rect.width()/2,rect.height()/2,mPaint);

        canvas.restore();
    }
    Path besizlePath = new Path();

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return gestureDetector.onTouchEvent(event);
    }










    void drawMoveCircle(Canvas canvas){

        mPaint.setColor(Color.RED);
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawCircle(c1X,c1Y,moveRadius,mPaint);

        mPaint.setColor(Color.WHITE);
        mPaint.setTextSize(defaultTextSize*scaleCircleFactor);
        mPaint.setStyle(Paint.Style.STROKE);
        Rect rect = new Rect();
        mPaint.getTextBounds(text,0,text.length(),rect);
        canvas.drawText(text,0,text.length(),c1X-rect.width()/2,c1Y+rect.height()/2,mPaint);
    }

    int bmpIndex = 0;
    void startDismission (){
        ValueAnimator valueAnimator = ValueAnimator.ofInt(0,mBurstBitmapsArray.length);
        valueAnimator.setDuration(600);
        valueAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animation) {
                int value = (int) animation.getAnimatedValue();
                bmpIndex = value;
                invalidate();
            }
        });
        valueAnimator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
            }

            @Override
            public void onAnimationEnd(Animator animation) {
                state = BUBBLE_STATE_DEFAUL;
                isShowBubble = false;
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        valueAnimator.start();
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    }

    //    GestureDetectorCompat.GestureDetectorCompatImplBase compatImplBase = new GestureDetectorCompat.GestureDetectorCompatImplBase()
    GestureDetector gestureDetector = new GestureDetector(getContext(), new GestureDetector.OnGestureListener() {
    @Override
    public boolean onDown(MotionEvent e) {
        c1X = (int) e.getX();
        c1Y = (int) e.getY();
//        compiteState();

        double dist =Math.hypot(c1X -cX,c1Y-cY);
        if (dist >minDelta  && dist < maxDelta){
            isShowBubble = true;
            compiteState();
        }else {
            isShowBubble = false;
        }

        return true;
    }

    @Override
    public void onShowPress(MotionEvent e) {

    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        return true;
    }

    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        c1X = (int) e2.getX();
        c1Y = (int) e2.getY();
        compiteState();
        return true;
    }

    @Override
    public void onLongPress(MotionEvent e) {

    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {


        state = BUBBLE_STATE_DISMISS;
        invalidate();
        startDismission();
        return false;
    }



    void compiteState(){
        double dist =Math.hypot(c1X -cX,c1Y-cY);
        if (dist < minDelta ){
            return;
        }
        if (dist < maxDelta){
            state = BUBBLE_STATE_CONNECT;
            double degree = Math.atan2(c1Y-cY,c1X - cX);
            double sinValue = Math.sin(degree);
            double cosValue = Math.cos(degree);

            int startX,startY,endX,endY;
            int startX1,startY1,endX1,endY1;
            int authorX = (cX + c1X)/2;
            int authorY = (cY+c1Y)/2;

            besizlePath.reset();
            startX= (int) (cX- defaultRadius*sinValue);
            startY = (int) (cY +defaultRadius*cosValue);
            endX = (int) (c1X -moveRadius* sinValue);
            endY = (int) (c1Y +moveRadius*cosValue);
            besizlePath.moveTo(startX,startY);
            besizlePath.quadTo(authorX,authorY,endX,endY);


            startX1= (int) (cX+ defaultRadius*sinValue);
            startY1 = (int) (cY -defaultRadius*cosValue);
            endX1 = (int) (c1X +moveRadius* sinValue);
            endY1 = (int) (c1Y -moveRadius*cosValue);

            besizlePath.lineTo(endX1,endY1);
            besizlePath.quadTo(authorX,authorY,startX1,startY1);
            besizlePath.close();
        }else {
            state = BUBBLE_STATE_APART;

        }

        invalidate();
    }



});
}
